package com.ee.chat.admin.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.Participant;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ee.chat.admin.service.IWithdrawService;
import com.ee.chat.admin.service.IOperationService;
import com.ee.chat.common.bean.Result;
import com.ee.chat.common.dao.*;
import com.ee.chat.common.entity.*;
import com.ee.chat.common.service.IPayService;
import com.ee.chat.common.service.IPushMessageService;
import com.ee.chat.common.service.IUpdateEntityService;
import com.ndhutu.ee.util.DateUtil;
import com.ndhutu.ee.util.StringUtil;
import com.ndhutu.ee.util.pay.ali.AliPayConfig;
import com.ndhutu.ee.util.pay.ali.AliPayUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Author Shane
 * @Date 2019/10/24 0:04
 */
@Service
public class WithdrawServiceImpl implements IWithdrawService {
    @Resource
    UserWithdrawLogMapper userWithdrawLogMapper;
    @Resource
    SysOrderMapper sysOrderMapper;
    @Resource
    UserWalletMapper userWalletMapper;
    @Resource
    UserCreditLogMapper userCreditLogMapper;
    @Resource
    PayChannelConfigMapper payChannelConfigMapper;
    @Resource
    SysConfigMapper sysConfigMapper;
    @Resource
    UserInviteLogMapper userInviteLogMapper;

    @Resource
    IOperationService operationService;
    @Resource
    IPushMessageService pushMessageService;
    @Resource
    IPayService payService;
    @Resource
    IUpdateEntityService updateEntityService;

    @Value("${spring.profiles.active}")
    String active;
    @Value("${pay.money}")
    Integer money;

    @Override
    public Result list(HttpServletRequest request, Integer userId, Integer status, Integer type, String time,
                       String field, String sort, Integer page, Integer limit) throws Exception {
        Map<String, Object> data = new HashMap<>();

        if(StringUtil.isEmpty(time) && userId == null && status == null){
            HttpSession session = request.getSession(true);
            List<String> userPermissions = (List<String>)session.getAttribute("userPermissions");
            if(!userPermissions.contains("/audit/withdraw/viewList")){
                data.put("withdrawLogs", new ArrayList<>());
                data.put("total", 0);

                return Result.returnSuccess(data);
            }
        }

        Date beginTime = null, endTime = null;
        if(!StringUtil.isEmpty(time)){
            String[] arr = time.split(" - ");
            beginTime = DateUtil.parse(arr[0]);
            endTime = DateUtil.parse(arr[1]);
        }

        Page<Map<String, Object>> p = new Page<>(page, limit);

        IPage<Map<String, Object>> iPage = userWithdrawLogMapper.list(p, userId, status, type, beginTime, endTime, field, sort);
        List<Map<String, Object>> withdrawLogs = iPage.getRecords();
        if(withdrawLogs != null && withdrawLogs.size() > 0) {
            for (Map<String, Object> map : withdrawLogs) {
                Integer inviteId = Integer.parseInt(map.get("userId").toString());
                Map<String, Object> inviteRechargeRate = userInviteLogMapper.getInviteRechargeRate(inviteId, map.get("createTime").toString());
                map.putAll(inviteRechargeRate);
            }
        }

        data.put("withdrawLogs", withdrawLogs);
        data.put("total", iPage.getTotal());

        operationService.addOperationLog(request, "查看提现审核列表数据");

        return Result.returnSuccess(data);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result audit(HttpServletRequest request, Integer id, Integer status, String reason) throws Exception {
        HttpSession session = request.getSession(true);
        AdminUser adminUser = (AdminUser)session.getAttribute("adminUser");
        Integer userId = adminUser.getId();

        UserWithdrawLog userWithdrawLog = userWithdrawLogMapper.selectById(id);
        if(userWithdrawLog.getStatus() != 0){
            return Result.returnFailure("该记录已经审核，不能重复审核");
        }

        Map<String, String> push = new HashMap<>();
        if(status == 3){    //通过
            if(userWithdrawLog.getType() == 1){
                //更新用户清退状态
                UserSet userSet = new UserSet();
                userSet.setUserId(userWithdrawLog.getUserId());
                userSet.setClean(3);
                updateEntityService.updateUserSet(userSet);
            }

            //1.打款
            PayChannelConfig remitConfig = payChannelConfigMapper.selectById(Integer.parseInt(sysConfigMapper.getValue("remit_alipay_config_id")));
            AliPayConfig aliPayConfig = (AliPayConfig) payService.getPayConfig(remitConfig);
            AlipayClient alipayClient = AliPayUtil.getCrtAlipayClient(aliPayConfig);

            AlipayFundTransUniTransferRequest alipayRequest = new AlipayFundTransUniTransferRequest();
            AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
            model.setOutBizNo(userWithdrawLog.getOrderNumber());
            if("prod".equals(active)){
                model.setTransAmount(new BigDecimal(userWithdrawLog.getAmount()+"").divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP).doubleValue()+"");
            }else{
                model.setTransAmount(new BigDecimal(money+"").divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP).doubleValue()+"");
            }
            model.setProductCode("TRANS_ACCOUNT_NO_PWD");
            model.setRemark("提现转账");
            model.setBizScene("DIRECT_TRANSFER");

            Participant payeeInfo = new Participant();
            payeeInfo.setIdentity(userWithdrawLog.getWithdrawNumber());
            payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
            payeeInfo.setName(userWithdrawLog.getWithdrawName());
            model.setPayeeInfo(payeeInfo);

            Map<String, Object> businessParams = new HashMap<>();
            businessParams.put("payer_show_name", aliPayConfig.getPayerShowName());
            model.setBusinessParams(JSONObject.toJSONString(businessParams));

            alipayRequest.setBizModel(model);
            String result = alipayClient.certificateExecute(alipayRequest).getBody();

            Map<String, Object> map = JSONObject.parseObject(result);
            Map<String, Object> response = (Map<String, Object>) map.get("alipay_fund_trans_uni_transfer_response");
            if(!("10000".equals(response.get("code")) && "Success".equals(response.get("msg")) && "SUCCESS".equals(response.get("status")))){
                //回滚事务
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return Result.returnFailure("打款失败，"+response.get("sub_msg"));
            }

            userWithdrawLog.setStatus(1);

            //更新系统订单
            SysOrder sysOrder = sysOrderMapper.selectByOrderNumber(userWithdrawLog.getOrderNumber());
            sysOrder.setStatus(1);
            sysOrder.setUpdateTime(new Date());
            sysOrderMapper.updateById(sysOrder);

            operationService.addOperationLog(request, "审核通过"+userWithdrawLog.getUserId()+"用户的提现申请");

            push.put("title", "提现申请审核通过");
            push.put("content", "你提交的提现申请审核已经通过，请注意查看");

        }else if(status == 2){  //拒绝
            if(userWithdrawLog.getType() == 1){
                //更新用户清退状态
                UserSet userSet = new UserSet();
                userSet.setUserId(userWithdrawLog.getUserId());
                userSet.setClean(1);
                updateEntityService.updateUserSet(userSet);
            }

            //退还积分
            UserWallet userWallet = userWalletMapper.getByUserId(userWithdrawLog.getUserId());
            userWallet.setActiveCredit(userWallet.getActiveCredit() + userWithdrawLog.getCredit());
            userWalletMapper.updateById(userWallet);

            //添加记录
            UserCreditLog userCreditLog = new UserCreditLog(userWithdrawLog.getUserId(), userWithdrawLog.getId(), 5, userWithdrawLog.getCredit()*1.0, "提现驳回返还");
            userCreditLogMapper.insert(userCreditLog);

            userWithdrawLog.setStatus(2);
            userWithdrawLog.setReason(reason);

            operationService.addOperationLog(request, "审核拒绝"+userWithdrawLog.getUserId()+"用户的提现申请，理由："+reason);

            push.put("title", "提现申请审核驳回");
            push.put("content", "你提交的提现申请审核被驳回，原因：" + reason);
        }else{
            return Result.returnFailure("参数错误");
        }

        //3.更新提现记录
        userWithdrawLog.setAuditUserId(userId);
        userWithdrawLog.setAuditTime(new Date());
        userWithdrawLogMapper.updateById(userWithdrawLog);

        push.put("type", "5");
        pushMessageService.pushGeneralMessage(userWithdrawLog.getUserId(), push);

        return Result.returnSuccess(null);
    }
}
